#include "HandInterface.hpp"

using namespace hi;

Barrier::Barrier(unsigned int count)
: m_threshold(count), m_count(count), m_generation(0)
{
	if (count == 0)
		boost::throw_exception(std::invalid_argument("count cannot be zero."));
}

bool Barrier::wait()
{
	boost::mutex::scoped_lock lock(m_mutex);
	unsigned int gen = m_generation;
	
	if (--m_count == 0)
	{
		m_generation++;
		m_count = m_threshold;
		m_cond.notify_all();
		return true;
	}
	
	while (gen == m_generation)
		m_cond.wait(lock);
	return false;
}

bool Barrier::decrement()
{
	boost::mutex::scoped_lock lock(m_mutex);
	
	m_threshold--; 
	
	if (--m_count == 0)
	{
		m_generation++;
		m_count = m_threshold;
		m_cond.notify_all();
		return true;
	}
	
	return false;
}

void Barrier::increment()
{
	boost::mutex::scoped_lock lock(m_mutex);
	m_threshold++;
}